<template>
  <view class="tictactoe-game-container">
    <!-- 头部信息 -->
    <view class="game-header">
      <view class="header-title">井字棋</view>
      <view class="user-info">{{ userName }}</view>
      <view class="game-status">{{ currentPlayer === userId ? '你的回合' : '对方回合' }}</view>
      <view class="game-tip">{{ gameTip }}</view>
    </view>

    <!-- 游戏区域 -->
    <view class="game-area">
      <h2 class="game-title"><i class="fa fa-th-large"></i> 井字棋对战</h2>

      <!-- 玩家列表 -->
      <view class="player-list">
        <view class="player-card" :class="{ 'current': currentPlayer === players[0]?.user_id }">{{ players[0]?.user_name || '等待加入...' }}
          <view class="piece-type"><i class="fa fa-times"></i></view>
        </view>
        <view class="player-card" :class="{ 'current': currentPlayer === players[1]?.user_id }">{{ players[1]?.user_name || '等待加入...' }}
          <view class="piece-type"><i class="fa fa-circle-o"></i></view>
        </view>
      </view>

      <!-- 游戏棋盘 -->
      <view class="game-board">
        <view class="board-row" v-for="(row, i) in gameState.board" :key="i">
          <view class="board-cell" v-for="(cell, j) in row" :key="j" @tap="handleCellTap(i, j)">
            <view class="cell-content" :class="cell">
              <i class="fa fa-times" v-if="cell === 'X'"></i>
              <i class="fa fa-circle-o" v-if="cell === 'O'"></i>
            </view>
          </view>
        </view>
      </view>

      <!-- 控制按钮 -->
      <view class="control-buttons">
        <button @tap="restartGame" class="restart-btn">重新开始</button>
        <button @tap="toggleReady" class="ready-btn">{{ isReady ? '取消准备' : '准备' }}</button>
        <button @tap="backToLobby" class="back-btn">返回大厅</button>
      </view>
    </view>
  </view>
</template>

<script setup>
import { ref, onMounted, reactive, onUnmounted } from 'vue';
import { 
  initGamePlayers,
  updatePlayerInfo,
  removePlayer
} from '@/utils/game-utils';
import { createGameConnection, GameType } from '@/utils/websocket-manager';
import { getCurrentUserInfo } from '@/utils/auth'


// 游戏状态
const gameState = reactive({
  board: [],
  rows: 3,
  cols: 3,
  winner: null,
  gameOver: false,
  tie: false
});

// 响应式变量
const userId = ref('');
const userName = ref('');
const roomId = ref('');
const players = ref([]);
const isReady = ref(false);
const currentPlayer = ref('');
const gameTip = ref('等待玩家加入...');

// WebSocket管理器
let wsManager = null;

/**
 * 初始化棋盘
 */
function initBoard() {
  gameState.board = [];
  gameState.winner = null;
  gameState.gameOver = false;
  gameState.tie = false;
  currentPlayer.value = players.value[0]?.user_id || '';
  gameTip.value = currentPlayer.value === userId.value ? '你的回合' : '对方回合';

  // 创建空棋盘
  for (let i = 0; i < gameState.rows; i++) {
    gameState.board[i] = [];
    for (let j = 0; j < gameState.cols; j++) {
      gameState.board[i][j] = null; // null: 空, 'X': X棋, 'O': O棋
    }
  }
}

/**
 * 处理棋盘格子点击
 */
function handleCellTap(i, j) {
  if (gameState.gameOver || currentPlayer.value !== userId.value || !isReady.value || gameState.board[i][j] !== null) {
    return;
  }

  // 落子
  const pieceType = currentPlayer.value === players.value[0]?.user_id ? 'X' : 'O';
  gameState.board[i][j] = pieceType;

  // 检查是否获胜
  if (checkWin(i, j, pieceType)) {
    gameState.winner = currentPlayer.value;
    gameState.gameOver = true;
    gameTip.value = `${players.value.find(p => p.user_id === currentPlayer.value)?.user_name} 获胜！`;
  } else if (checkTie()) {
    gameState.tie = true;
    gameState.gameOver = true;
    gameTip.value = '平局！';
  } else {
    // 切换玩家
    currentPlayer.value = currentPlayer.value === players.value[0]?.user_id ? players.value[1]?.user_id : players.value[0]?.user_id;
    gameTip.value = currentPlayer.value === userId.value ? '你的回合' : '对方回合';
  }

  // 发送落子信息到服务器 (实际应用中需要实现)
  // sendMove(i, j, pieceType);
}

/**
 * 检查是否获胜
 */
function checkWin(i, j, pieceType) {
  // 检查行
  let rowWin = true;
  for (let k = 0; k < gameState.cols; k++) {
    if (gameState.board[i][k] !== pieceType) {
      rowWin = false;
      break;
    }
  }
  if (rowWin) return true;

  // 检查列
  let colWin = true;
  for (let k = 0; k < gameState.rows; k++) {
    if (gameState.board[k][j] !== pieceType) {
      colWin = false;
      break;
    }
  }
  if (colWin) return true;

  // 检查对角线 (从左上到右下)
  if (i === j) {
    let diagWin = true;
    for (let k = 0; k < gameState.rows; k++) {
      if (gameState.board[k][k] !== pieceType) {
        diagWin = false;
        break;
      }
    }
    if (diagWin) return true;
  }

  // 检查对角线 (从右上到左下)
  if (i + j === gameState.rows - 1) {
    let diagWin = true;
    for (let k = 0; k < gameState.rows; k++) {
      if (gameState.board[k][gameState.rows - 1 - k] !== pieceType) {
        diagWin = false;
        break;
      }
    }
    if (diagWin) return true;
  }

  return false;
}

/**
 * 检查是否平局
 */
function checkTie() {
  for (let i = 0; i < gameState.rows; i++) {
    for (let j = 0; j < gameState.cols; j++) {
      if (gameState.board[i][j] === null) {
        return false; // 还有空位，不是平局
      }
    }
  }
  return true; // 棋盘已满，平局
}

/**
 * 重新开始游戏
 */
function restartGame() {
  initBoard();
}

/**
 * 切换准备状态
 */
function toggleReady() {
  isReady.value = !isReady.value;
  
  // 发送WebSocket消息通知其他玩家
  if (wsManager && wsManager.getConnected()) {
    const message = {
      type: 4, // READY
      user_id: userId.value,
      user_name: userName.value,
      room_id: roomId.value,
      content: isReady.value.toString(),
      time: Math.floor(Date.now() / 1000)
    };
    wsManager.send(message);
  }
}

/**
 * 返回游戏大厅
 */
function backToLobby() {
  console.log('=== backToLobby 被调用 ===')
  
  // 发送离开房间消息
  if (wsManager && wsManager.getConnected()) {
    console.log('backToLobby: 发送离开房间消息')
    try {
      const leaveMessage = {
        type: 2, // LEAVE
        user_id: userId.value,
        user_name: userName.value,
        room_id: roomId.value,
        content: `${userName.value} 离开了游戏房间`,
        time: Math.floor(Date.now() / 1000)
      }
      wsManager.send(leaveMessage)
      
      // 等待消息发送完成后再关闭连接
      setTimeout(() => {
        closeWebSocketConnection()
      }, 200) // 增加延迟确保消息发送
    } catch (error) {
      console.error('发送离开消息失败:', error)
      closeWebSocketConnection()
    }
  } else {
    closeWebSocketConnection()
  }
}

function closeWebSocketConnection() {
  // 强制关闭WebSocket连接
  if (wsManager) {
    console.log('backToLobby: 强制关闭WebSocket连接')
    try {
      wsManager.close();
    } catch (error) {
      console.error('关闭WebSocket连接时出错:', error)
    }
    wsManager = null;
  }

  // 清除房间ID和游戏状态
  uni.removeStorageSync('roomId')
  
  // 重置游戏状态
  gameState.value = {
    board: Array(9).fill(''),
    currentPlayer: 'X',
    winner: null,
    isDraw: false,
    gameStarted: false,
    gameOver: false
  }
  
  players.value = []
  gameTip.value = '等待玩家加入...'

  // 导航回游戏空间
  console.log('backToLobby: 导航回游戏空间')
  uni.navigateBack();
}

/**
 * 更新玩家列表
 */
function updatePlayerList(message) {
  console.log('更新玩家列表:', message)
  
  // 如果是加入消息，添加到玩家列表
  if (message.type === 1 || message.type === 'join') {
    const newPlayer = {
      user_id: message.user_id,
      user_name: message.user_name,
      ready: false
    }
    
    // 检查是否已存在
    const existingIndex = players.value.findIndex(p => p.user_id === newPlayer.user_id)
    if (existingIndex === -1) {
      players.value.push(newPlayer)
      console.log('添加新玩家:', newPlayer)
    } else {
      players.value[existingIndex] = newPlayer
      console.log('更新玩家信息:', newPlayer)
    }
  }
  // 如果是离开消息，从玩家列表中移除
  else if (message.type === 2 || message.type === 'leave') {
    const playerIndex = players.value.findIndex(p => p.user_id === message.user_id)
    if (playerIndex !== -1) {
      const removedPlayer = players.value.splice(playerIndex, 1)[0]
      console.log('移除玩家:', removedPlayer)
    }
  }
  
  // 强制触发响应式更新
  players.value = [...players.value]
  
  console.log('更新后的玩家列表:', players.value)
  
  // 更新游戏提示
  if (players.value.length === 1) {
    gameTip.value = '等待其他玩家加入...'
  } else if (players.value.length >= 2) {
    gameTip.value = '玩家已就位，准备开始游戏！'
  } else {
    gameTip.value = '等待玩家加入...'
  }
}

/**
 * 更新玩家准备状态
 */
function updatePlayerReadyStatus(message) {
  console.log('更新玩家准备状态:', message)
  
  // 更新指定玩家的准备状态
  if (message.user_id) {
    const playerIndex = players.value.findIndex(p => p.user_id === message.user_id);
    if (playerIndex !== -1) {
      players.value[playerIndex].ready = message.ready || false;
    }
  }
}

/**
 * 处理游戏操作
 */
function handleGameOperation(message) {
  console.log('处理游戏操作:', message)
  // 处理井字棋游戏操作
}

/**
 * 更新游戏状态
 */
function updateGameState(message) {
  console.log('更新游戏状态:', message)
  // 处理游戏状态更新
}

/**
 * 处理游戏开始
 */
function handleGameStart(message) {
  console.log('游戏开始:', message)
  // 处理游戏开始
}

/**
 * 处理游戏结束
 */
function handleGameEnd(message) {
  console.log('游戏结束:', message)
  // 处理游戏结束
}

/**
 * 处理用户列表更新
 */
function handleUserListUpdate(message) {
  console.log('收到用户列表更新:', message)
  
  try {
    let userList = [];
    
    // 处理不同的消息格式
    if (message.content) {
      if (typeof message.content === 'string') {
        userList = JSON.parse(message.content);
      } else if (Array.isArray(message.content)) {
        userList = message.content;
      }
    } else if (message.data && Array.isArray(message.data)) {
      userList = message.data;
    }
    
    console.log('解析后的用户列表:', userList);
    
    // 更新玩家列表
    players.value = userList.map(user => ({
      user_id: user.user_id || user.userId,
      user_name: user.user_name || user.userName,
      ready: user.ready || false
    }));
    
    // 强制触发响应式更新
    players.value = [...players.value];
    
    console.log('更新后的玩家列表:', players.value);
    
    // 更新游戏提示
    if (players.value.length === 1) {
      gameTip.value = '等待其他玩家加入...';
    } else if (players.value.length >= 2) {
      gameTip.value = '玩家已就位，准备开始游戏！';
    } else {
      gameTip.value = '等待玩家加入...';
    }
    
    // 显示用户列表更新提示
    uni.showToast({
      title: `房间用户更新: ${players.value.length}人`,
      icon: 'none',
      duration: 1500
    });
  } catch (error) {
    console.error('解析用户列表失败:', error);
    console.error('原始消息:', message);
  }
}

/**
 * 处理房间人数更新
 */
function handleRoomUserCount(message) {
  console.log('收到房间人数更新:', message)
  
  if (message.data) {
    const { user_count, max_users } = message.data;
    console.log(`房间人数: ${user_count}/${max_users}`);
    
    // 更新游戏提示
    if (user_count === 1) {
      gameTip.value = '等待其他玩家加入...';
    } else if (user_count >= 2) {
      gameTip.value = '玩家已就位，准备开始游戏！';
    }
    
    // 强制触发响应式更新
    gameTip.value = gameTip.value;
  }
}

// 生命周期钩子
onMounted(() => {
  // 获取用户信息和房间ID
  const userInfo = getCurrentUserInfo();
  userId.value = userInfo?.userId || 'user123';
  userName.value = userInfo?.userName || '玩家1';
  roomId.value = uni.getStorageSync('roomId') || 'room012';

  // 初始化玩家列表
  players.value = initGamePlayers(userId.value, userName.value, 2);

  // 初始化棋盘
  initBoard();

  // 初始化WebSocket连接
  console.log('井子棋游戏初始化WebSocket，房间ID:', roomId.value)
  
  if (!roomId.value) {
    console.error('房间ID为空，无法初始化WebSocket')
    uni.showToast({
      title: '房间ID为空',
      icon: 'none',
      duration: 2000
    })
    return
  }
  
  if (!userId.value || !userName.value) {
    console.error('用户信息为空，无法初始化WebSocket')
    uni.showToast({
      title: '用户信息为空',
      icon: 'none',
      duration: 2000
    })
    return
  }
  
  try {
    wsManager = createGameConnection(GameType.TICTACTOE, roomId.value, {
      onOpen: () => {
        console.log('井字棋WebSocket连接成功')
        // 重置防止重连标志，允许正常重连
        wsManager.resetPreventReconnect()
        uni.showToast({
          title: '连接成功',
          icon: 'success',
          duration: 1000
        })
        
        // 连接成功后立即发送加入消息
        const joinMessage = {
          type: 1, // JOIN
          user_id: userId.value,
          user_name: userName.value,
          room_id: String(roomId.value),
          content: `${userName.value} 加入了游戏房间`,
          time: Math.floor(Date.now() / 1000)
        }
        wsManager.send(joinMessage)
      },
      onJoin: (message) => {
        console.log('用户加入:', message)
        updatePlayerList(message)
      },
      onLeave: (message) => {
        console.log('用户离开:', message)
        updatePlayerList(message)
      },
      onReady: updatePlayerReadyStatus,
      onGameOp: handleGameOperation,
      onGameState: updateGameState,
      onGameStart: handleGameStart,
      onGameEnd: handleGameEnd,
      onUserListUpdate: handleUserListUpdate,
      onRoomUserCount: handleRoomUserCount,
      onError: (error) => {
        console.error('井字棋WebSocket连接错误:', error)
        uni.showToast({
          title: '连接失败',
          icon: 'none',
          duration: 2000
        })
      }
    });
    
    console.log('WebSocket管理器创建完成，开始连接')
    wsManager.connect().then(() => {
      console.log('WebSocket连接成功')
    }).catch((error) => {
      console.error('WebSocket连接失败:', error)
    })
  } catch (error) {
    console.error('创建WebSocket管理器失败:', error)
  }
});

onUnmounted(() => {
  if (wsManager) {
    wsManager.close();
  }
});
</script>

<style scoped>
.tictactoe-game-container {
  padding: 16px;
  min-height: 100vh;
  background: linear-gradient(135deg, #e0e7ff 0%, #f8fafc 100%);
}

.game-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding: 10px;
  background: #fff;
  border-radius: 10px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
}

.header-title {
  font-size: 18px;
  font-weight: bold;
  color: #6366f1;
}

.user-info {
  font-size: 14px;
  color: #1f2937;
}

.game-status {
  font-size: 14px;
  font-weight: bold;
  color: #6366f1;
}

.game-tip {
  font-size: 14px;
  color: #6b7280;
}

.game-area {
  background: #fff;
  border-radius: 16px;
  box-shadow: 0 4px 32px rgba(99, 102, 241, 0.2);
  padding: 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.game-title {
  font-size: 18px;
  font-weight: bold;
  color: #4f46e5;
  margin-bottom: 16px;
  display: flex;
  align-items: center;
}

.game-title i {
  margin-right: 8px;
}

.player-list {
  display: flex;
  justify-content: space-between;
  width: 100%;
  max-width: 320px;
  margin-bottom: 16px;
  gap: 10px;
}

.player-card {
  flex: 1;
  background: #f3f4f6;
  border-radius: 10px;
  padding: 10px;
  text-align: center;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.player-card.current {
  border: 2px solid #6366f1;
  background: #f0f4ff;
}

.piece-type {
  margin-top: 4px;
  font-size: 16px;
}

.game-board {
  margin: 20px 0;
  background: #ffffff;
  border-radius: 12px;
  padding: 10px;
  box-shadow: 0 2px 12px rgba(99, 102, 241, 0.1);
}

.board-row {
  display: flex;
}

.board-cell {
  width: 80px;
  height: 80px;
  border: 1px solid #e2e8f0;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.2s;
}

.board-cell:hover {
  background: #f3f4f6;
}

.cell-content {
  font-size: 32px;
  font-weight: bold;
}

.cell-content.X {
  color: #ef4444;
}

.cell-content.O {
  color: #3b82f6;
}

.control-buttons {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  justify-content: center;
}

.restart-btn, .ready-btn, .back-btn {
  padding: 8px 16px;
  border-radius: 50px;
  font-weight: bold;
  border: none;
  cursor: pointer;
  transition: all 0.2s;
}

.restart-btn {
  background: linear-gradient(90deg, #6366f1 0%, #818cf8 100%);
  color: white;
}

.ready-btn {
  background: #f3f4f6;
  color: #1f2937;
}

.back-btn {
  background: #fee2e2;
  color: #dc2626;
}

.restart-btn:hover {
  opacity: 0.9;
  transform: scale(1.05);
}
</style>